﻿using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace SCM.Common
{
    public class DbContext : SqlSugarClient
    {
        //更新数据最多10000条每次
        public int AddOrSaveDataMax = 10000;
        private static string sqlConnect = "";
        private static DbType dbtype = DbType.MySql;
        public static void Init(string sqlConnect, DbType dbtype)
        {
            DbContext.sqlConnect = sqlConnect;
            DbContext.dbtype = dbtype;
        }
        public DbContext()
            : base(new ConnectionConfig()
            {
                ConnectionString = sqlConnect,
                DbType = dbtype,
                InitKeyType = InitKeyType.SystemTable,
                IsAutoCloseConnection = true,
                IsShardSameThread = true,
                MoreSettings = new ConnMoreSettings()
                {
                    //IsWithNoLockQuery = true
                }
            })
        {
//#if DEBUG
//            Aop.OnLogExecuting = (sql, pars) =>
//            {
//                Console.WriteLine(sql + "\r\n" + Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
//            };
//#endif
        }

        public DbContext(string sqlConnect, DbType dbtype) : base(new ConnectionConfig()
        {
            ConnectionString = sqlConnect,
            DbType = dbtype,
            InitKeyType = InitKeyType.SystemTable,
            IsAutoCloseConnection = true,
            IsShardSameThread = true,
            MoreSettings = new ConnMoreSettings()
            {
                //IsWithNoLockQuery = true
            }
        })
        {
//#if DEBUG
//            Aop.OnLogExecuting = (sql, pars) =>
//            {
//                Console.WriteLine(sql + "\r\n" + Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
//            };
//#endif
        }

        public bool Insert<T>(T model) where T : class, new()
        {
            return this.Insertable<T>(model).ExecuteCommandIdentityIntoEntity();
        }

        public virtual bool InsertIgnoreNull<T>(T model) where T : class, new()
        {
            return Insertable<T>(model).IgnoreColumns(true, false).ExecuteCommandIdentityIntoEntity();
        }
        public virtual bool Insert<T>(List<T> list) where T : class, new()
        {
            return Insertable<T>(list).ExecuteCommandIdentityIntoEntity();
        }

        public virtual T Save<T>(T model) where T : class, new()
        {
            return Saveable<T>(model).ExecuteReturnEntity();
        }

        public virtual List<T> Save<T>(List<T> list) where T : class, new()
        {
            return Saveable<T>(list).ExecuteReturnList();
        }

        public virtual int SaveOrUpdate<T>(T model) where T : class, new()
        {
            return Saveable<T>(model).ExecuteCommand();
        }

        public virtual int SaveOrUpdate<T>(List<T> list) where T : class, new()
        {
            return Saveable<T>(list).ExecuteCommand();
        }

        public virtual bool Delete<T>(dynamic id) where T : class, new()
        {
            return Deleteable<T>(id).ExecuteCommand() > 0;
        }
        public virtual bool Delete<T>(Expression<Func<T, bool>> where) where T : class, new()
        {
            return Deleteable<T>(where).ExecuteCommand() > 0;
        }

        public virtual bool Delete<T>(T model) where T : class, new()
        {
            return Deleteable(model).ExecuteCommand() > 0;
        }
        public virtual bool Delete<T>(List<dynamic> ids) where T : class, new()
        {

            return Deleteable<T>(ids).ExecuteCommand() > 0;
        }
        public virtual bool Modify<T>(Expression<Func<T, object>> columns, Expression<Func<T, bool>> where) where T : class, new()
        {
            return Updateable<T>().UpdateColumns(columns).Where(where).ExecuteCommand() > 0;
        }

        public virtual bool Modify<T>(T model, Expression<Func<T, object>> columns = null) where T : class, new()
        {
            if (columns != null)
                return Updateable<T>(model).UpdateColumns(columns).ExecuteCommand() > 0;
            return Updateable<T>(model).ExecuteCommand() > 0;
        }
        public virtual bool Modify<T>(List<T> list) where T : class, new()
        {
            return Updateable<T>(list).ExecuteCommand() > 0;
        }

        public virtual T Get<T>(dynamic id) where T : class, new()
        {
            return Queryable<T>().InSingle(id);
        }
        public List<T> Get<T>(dynamic[] ids) where T : class, new()
        {
            return Queryable<T>().In(ids).ToList();
        }

        public virtual List<T> ListIn<T>(Expression<Func<T, object>> inWhere, IEnumerable items) where T : class, new()
        {
            return Queryable<T>().In(inWhere, items).ToList();
        }
        public virtual List<T> List<T>() where T : class, new()
        {
            return Queryable<T>().ToList();
        }
        public virtual List<T> List<T>(Expression<Func<T, bool>> queryExp, Expression<Func<T, object>> orderExp = null, OrderByType orderType = OrderByType.Desc) where T : class, new()
        {
            var query = Queryable<T>();
            if (queryExp != null)
            {
                query = query.Where(queryExp);
            }
            if (orderExp != null)
            {
                return query.OrderBy(orderExp, orderType).ToList();
            }
            return query.ToList();
        }

        public T QueryOne<T>(Expression<Func<T, bool>> queryExp) where T : class, new()
        {
            var query = Queryable<T>();
            if (queryExp != null)
            {
                query = query.Where(queryExp);
                return query.First();

            }
            else
            {
                return query.First();
            }
        }

        public List<T> GetListPage<T>(Expression<Func<T, bool>> queryExp, PageInfo info, Expression<Func<T, object>> orderExp = null, OrderByType orderType = OrderByType.Desc) where T : class, new()
        {
            if (info == null)
                throw new ArgumentNullException("分页信息不能为空");
            var query = Queryable<T>();
            if (queryExp != null)
            {
                query = query.Where(queryExp);
            }
            List<T> list = null;
            int totalCount = 0;
            if (orderExp != null)
            {
                list = query.OrderBy(orderExp, orderType).ToPageList(info.PageIndex, info.PageSize, ref totalCount);
            }
            else
            {
                list = query.ToPageList(info.PageIndex, info.PageSize, ref totalCount);
            }
            if (list == null) return null;
            info.DataCount = totalCount;
            return list;
        }
    }
}
